export {}

/* 
  函数类型注解
    参数：
      1.参数名
        - 类型的参数名和值的参数名不需要一致
        - 最终的函数的签名以类型为准，所以尽量将类型中的参数名写得有意义一些
      2.参数的数量
        - 值中的参数数量不能多余类型定义的参数数量
        - 为了兼容旧版本js函数，所以值中的参数个数可以少于类型中定义的参数个数
      3.参数的类型
        - strictFunctionTypes 开启时
          - 值中的参数类型不能比类型中的参数类型还具体
              值的参数类型 > 类型的参数类型
        - strictFunctionTypes 关闭时（双向协变）
          - 此时只要值中的参数类型被类型中的参数类型所包含即可
        strictFunctionTypes 对于方法无效

    返回值：
      void
        - void表示没有返回值或返回值没用

*/

type MyFunction = (str: string, num: number) => string

let fn: MyFunction = (a: string) => "hello"

type MyFunction2 = (str: string | number) => string

// let fn2: MyFunction2 = (a: string) => "hello" // 这种方式赋值时，容易导致运行时的异常

interface MyObj {
  test(str: string | number): void
}

let obj: MyObj = {
  test(a: string) {}, // strictFunctionTypes对于方法无效，所以这里可能会出现运行时异常
}

type MyFunction3 = () => void
let fn3: MyFunction3 = () => "hello"
